using System.Collections.Generic;
using System.Linq;
using GameFramework;
using UnityEngine;
using UnityEngine.Rendering;
using UnityGameFramework.Runtime;

namespace StarForce.Manager
{
    /// <summary>
    /// 三消游戏检查器
    /// </summary>
    public partial class EliminateInspectManager
    {
        private static EliminateInspectManager m_Instance;

        public static EliminateInspectManager Instance
        {
            get
            {
                if (m_Instance == null)
                {
                    m_Instance = new EliminateInspectManager();
                }

                return m_Instance;
            }
        }

        private List<int> m_CurCanClearNext;

        private List<int> m_CanClearNext;

        private EliminateFill m_EliminateFill;

        /// <summary>
        /// 消除队列
        /// </summary>
        private Queue<EliminateCommand> m_EliminateCommands;


        private EliminateInspectManager()
        {
            m_EliminateCommands = new Queue<EliminateCommand>();
            m_CurCanClearNext = new List<int>();
            m_CanClearNext = new List<int>();

            m_EliminateFill = new EliminateFill(this);
        }


        /// <summary>
        /// 检查右边
        /// </summary>
        /// <param name="startIndex"></param>
        public void CheckRight(int startIndex)
        {
            if (!m_CanClearNext.Contains(GameEntry.Eliminate.GetItem(startIndex).Pos))
            {
                EliminateItem itemRight = GameEntry.Eliminate.GetItem(startIndex).RItem;
                EliminateType type = GameEntry.Eliminate.GetItem(startIndex).Type;
                m_CurCanClearNext.Add(startIndex);
                while (itemRight != null)
                {
                    if (type == itemRight.Type)
                    {
                        m_CurCanClearNext.Add(itemRight.Pos);
                        itemRight = itemRight.RItem;
                    }
                    else
                    {
                        break;
                    }
                }

                if (m_CurCanClearNext.Count >= 3)
                {
                    EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                    command.AddPos(m_CurCanClearNext);
                    AddCommand(command);
//                    Log.Info("有横排消除----:"); 
                    for (int i = 0; i < m_CurCanClearNext.Count; i++)
                    {
                        m_CanClearNext.Add(m_CurCanClearNext[i]);
                    }

//                    Log.Info("-----------:"); 
                }

                m_CurCanClearNext.Clear();
            }
        }


        /// <summary>
        /// 检测全部
        /// </summary>
        public void CheckAll()
        {
            int startIndex = 0;
            int endIndex = startIndex + 1;
            int allIndex = Constant.EliminateGameConfig.VCount * Constant.EliminateGameConfig.HCount - 1;
            EliminateItem item = GameEntry.Eliminate.GetItem(startIndex);
            EliminateType type = item.Type;
            List<int> canClear = new List<int>();

            canClear.Add(item.Pos);

            while (startIndex <= allIndex - 2 && endIndex <= allIndex)
            {
                CheckRight(startIndex);
                CheckRight(endIndex);

                //检查下方一列
                if (item.BItem != null &&
                    GameEntry.Eliminate.GetItem(endIndex).TItem != null &&
                    type == GameEntry.Eliminate.GetItem(endIndex).Type)
                {
                    canClear.Add(GameEntry.Eliminate.GetItem(endIndex).Pos);
                    endIndex++;
                }
                else
                {
                    if (canClear.Count >= 3)
                    {
                        EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                        command.AddPos(canClear);
                        AddCommand(command);
//                        Log.Info("有竖排消除----:");
//                        for (int i = 0; i < canClear.Count; i++)
//                        {
//                            Log.Info("index:"+canClear[i]);
//                        }
//                        Log.Info("-------:");
                        startIndex = endIndex;
                        endIndex = startIndex + 1;
                    }
                    else
                    {
                        startIndex += canClear.Count;
                        endIndex = startIndex + 1;
                    }

                    item = GameEntry.Eliminate.GetItem(startIndex);
                    type = item.Type;
                    canClear.Clear();
                    canClear.Add(item.Pos);
                }
            }

            if (canClear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(canClear);
                AddCommand(command);
//                Log.Info("有竖排消除----:");
//                for (int i = 0; i < canClear.Count; i++)
//                {
//                    Log.Info("index:" + canClear[i]);
//                }
//                Log.Info("---------:");
            }

            ImplementEliminateCommand();
        }


        /// <summary>
        /// 检查横向
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckHorizontal(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem itemLeft = item;
            EliminateType type = item.Type;
            clear.Add(itemLeft.Pos);
            //检查左边
            while (itemLeft.LItem != null && itemLeft.LItem.Type == type)
            {
                clear.Add(itemLeft.LItem.Pos);
                itemLeft = itemLeft.LItem;
            }

            //检查右边
            EliminateItem itemRight = item;
            while (itemRight.RItem != null && itemRight.RItem.Type == type)
            {
                clear.Add(itemRight.RItem.Pos);
                itemRight = itemRight.RItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 检查竖向
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckVertical(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem itemTop = item;
            EliminateType type = item.Type;
            clear.Add(itemTop.Pos);
            while (itemTop.TItem != null && itemTop.TItem.Type == type)
            {
                clear.Add(itemTop.TItem.Pos);
                itemTop = itemTop.TItem;
            }

            EliminateItem itemBottom = item;
            while (itemBottom.BItem != null && itemBottom.BItem.Type == type)
            {
                clear.Add(itemBottom.BItem.Pos);
                itemBottom = itemBottom.BItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }


        /// <summary>
        /// 添加一条消除指令
        /// </summary>
        /// <param name="command"></param>
        public void AddCommand(EliminateCommand command)
        {
            if (command != null)
            {
                m_EliminateCommands.Enqueue(command);
            }
        }


        /// <summary>
        /// 执行消除命令
        /// </summary>
        public void ImplementEliminateCommand()
        {
            int count = 0;
            while (m_EliminateCommands.Count > 0)
            {
                EliminateCommand command = m_EliminateCommands.Dequeue();

                //todo 执行消除命令

                Log.Info("执行消除--：：" + command.EliminateType);
                for (int i = 0; i < command.Pos.Count; i++)
                {
                    Log.Info("消除元素:" + command.Pos[i]);
                }

                Log.Info("----------------------");

                GameEntry.Eliminate.ClearItem(command.Pos);
                ReferencePool.Release(command);
                count++;
            }

            if (count>0)
            {
                m_EliminateFill.AllFill();
            }
        }


        /// <summary>
        /// 检测上方
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckTop(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem item1 = item;
            EliminateType type = item1.Type;
            clear.Add(item1.Pos);
            while (item1.TItem != null && item1.TItem.Type == type)
            {
                clear.Add(item1.TItem.Pos);
                item1 = item1.TItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 检测下方
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckBottom(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem item1 = item;
            EliminateType type = item1.Type;
            clear.Add(item1.Pos);
            while (item1.BItem != null && item1.BItem.Type == type)
            {
                clear.Add(item1.BItem.Pos);
                item1 = item1.BItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 检测右方
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckRight(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem item1 = item;
            EliminateType type = item1.Type;
            clear.Add(item1.Pos);
            while (item1.RItem != null && item1.RItem.Type == type)
            {
                clear.Add(item1.RItem.Pos);
                item1 = item1.RItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 检测左方
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool CheckLeft(EliminateItem item)
        {
            List<int> clear = new List<int>();
            EliminateItem item1 = item;
            EliminateType type = item1.Type;
            clear.Add(item1.Pos);
            while (item1.LItem != null && item1.LItem.Type == type)
            {
                clear.Add(item1.LItem.Pos);
                item1 = item1.LItem;
            }

            if (clear.Count >= 3)
            {
                EliminateCommand command = ReferencePool.Acquire<EliminateCommand>().Fill(type);
                command.AddPos(clear);
                EliminateInspectManager.Instance.AddCommand(command);
                return true;
            }

            return false;
        }
    }
}